/**
* @program: src
*
* @description:grpc客户端
*
* @author: Mr.chen
*
* @create: 2022-04-11 17:43
**/
package grpcclient

import (
	"context"
	"do_demo/srv/app/logic/api/internal/config"
	"do_demo/srv/common/etcdv3"
	"do_demo/srv/common/grpc/auth"
	"do_demo/srv/common/helper"
	"do_demo/srv/common/interceptor/clientinterceptors"
	grpc_middleware "github.com/grpc-ecosystem/go-grpc-middleware"
	"google.golang.org/grpc"
	"google.golang.org/grpc/balancer/roundrobin"
	"google.golang.org/grpc/keepalive"
	"google.golang.org/grpc/resolver"
	"time"
)

var (
	// grpc options
	grpcKeepAliveTime    = time.Duration(10) * time.Second
	grpcKeepAliveTimeout = time.Duration(3) * time.Second
	grpcBackoffMaxDelay  = time.Duration(3) * time.Second
	grpcMaxSendMsgSize   = 1 << 24
	grpcMaxCallMsgSize   = 1 << 24
)

const (
	// grpc options
	grpcInitialWindowSize     = 1 << 24
	grpcInitialConnWindowSize = 1 << 24
)
// 初始化grpc客户端
func NewClientConn(c *config.Config) *grpc.ClientConn {
	ctx, cancel := context.WithTimeout(context.Background(), time.Duration(1) * time.Second) // 设置超时时间
	defer cancel()
	r := etcdv3.NewServiceDiscovery(c.Etcd.Endpoints)
	resolver.Register(r)
	interceptor := grpc.UnaryClientInterceptor(grpc_middleware.ChainUnaryClient(
		clientinterceptors.UnaryTracingInterceptor,
		clientinterceptors.PrometheusInterceptor,
		clientinterceptors.TimeoutInterceptor(5*time.Second),
	))
	rpcauth := auth.Credential{
		App:   "test",
		Token: "testOK",
	}
	//rpcauth := auth.ParseCredential(ctx)
	conn, err := grpc.DialContext(ctx,r.Scheme()+"://0.0.0.0/testsrv.apiRpc.logic",
		[]grpc.DialOption{
			grpc.WithTransportCredentials(helper.GetClientCredentials()),
			//grpc.WithInsecure(), // 不需要证书
			grpc.WithInitialWindowSize(grpcInitialWindowSize),
			grpc.WithInitialConnWindowSize(grpcInitialConnWindowSize),
			grpc.WithDefaultCallOptions(grpc.MaxCallRecvMsgSize(grpcMaxCallMsgSize)),
			grpc.WithDefaultCallOptions(grpc.MaxCallSendMsgSize(grpcMaxSendMsgSize)),
			grpc.WithBackoffMaxDelay(grpcBackoffMaxDelay),
			grpc.WithKeepaliveParams(keepalive.ClientParameters{
				Time:                grpcKeepAliveTime,
				Timeout:             grpcKeepAliveTimeout,
				PermitWithoutStream: true,
			}),
			grpc.WithBalancerName(roundrobin.Name),
			grpc.WithChainUnaryInterceptor(interceptor),
			grpc.WithPerRPCCredentials(&rpcauth),// 自定义token验证
		}...,
	)
	if err != nil {
		panic(err)
	}
	return conn
	//return pb.NewLogicClient(conn), err
}